__author__ = 'selab'
from rest_framework.decorators import api_view, renderer_classes, authentication_classes, permission_classes
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from yaasapp.serializers import AuctionSerializer,AuctionAddSerializer
from yaasapp.models import AuctionData, Biders
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from django.contrib.auth.models import User
from rest_framework.views import APIView
from django.http import HttpResponse
from yaasapp.views import emailView
from django.http import Http404
from datetime import datetime

class JSONResponse(HttpResponse):
    """
    An HttpResponse that renders its content into JSON.
    """
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

@csrf_exempt
@api_view(['GET', 'PUT'])
@renderer_classes([JSONRenderer,])
def auc_list(request, pk=''):
    if pk:
        try:
            auc = AuctionData.objects.get(pk=pk)
        except AuctionData.DoesNotExist:
            return HttpResponse(status=404)

        if request.method == 'GET':
            serializer = AuctionSerializer(auc)
            return JSONResponse(serializer.data)
    else:
        if request.method == 'GET':
            auc = AuctionData.objects.all()
            serializer = AuctionSerializer(auc, many=True)
            return Response(serializer.data)

        elif request.method == 'PUT':
            data = JSONParser().parse(request)
            print data
            serializer = AuctionAddSerializer(data=data)
            if serializer.is_valid():
                serializer.save()
                return JSONResponse(serializer.data, status=201)
            else:
                return JSONResponse(serializer.errors, status=400)

@csrf_exempt
@api_view(['POST'])
@authentication_classes([BasicAuthentication])
@permission_classes([IsAuthenticated])
def auc_bid(request, id):
    try:
        auc = AuctionData.objects.get(pk=id)
    except AuctionData.DoesNotExist:
        return HttpResponse(status=404)

    if AuctionData.getById(id).status != 'active':
        return JSONResponse({'msg':'An auction is not active anymore for bid.'})

    # Owner of the auction can not bid
    if AuctionData.getById(id).user == request.user.username:
        return JSONResponse({'msg':'Since you are the owner of the item you cant bid on it.'})

    try:
            biderlist = auc.bider.all().order_by("-bidDate")
            cbider = biderlist[0]
            # If the Bidder is already winning the product
            if request.user.is_authenticated() and AuctionData.getById(id).user != request.user.username and str(cbider) == str(request.user.username):
                return JSONResponse({'msg':'You are winning this product at the moment.'})
    except:
        bider = Biders(bider=request.user.username, bidDate=datetime.now(), bidItemID=auc.id)
        bider.save()
        auc.bider.add(bider)
        emailView([(User.objects.get(username=auc.user)).email,request.user.email,],'Bid has been placed.','A Bid has been placed for this item.')

    try:
        bidprice = float(request.DATA.get('cPrice', ''))
    except:
        return JSONResponse({'msg':'Check the fields, It should contain at least.', 'cPrice':''})

     #If the price is more and has not been modified by other users before it was saved.
    if bidprice >= (float(auc.cPrice)+0.01):
                auc.cPrice = request.DATA.get('cPrice', '')
                auc.version = auc.version + 1
                auc.save()

                #Checks it the list of bider for the item is empty, if yes create one.
                if not auc.bider.all():
                    bider = Biders(bider=request.user.username, bidDate=datetime.now(), bidItemID=auc.id)
                    bider.save()
                    auc.bider.add(bider)
                    emailView([(User.objects.get(username=auc.user)).email,request.user.email,],'Bid has been placed.','A Bid has been placed for this item.')
                else:
                    boolean = False
                    listbider = [(User.objects.get(username=auc.user)).email,]
                    for i in auc.bider.all():
                        if str(i) == str(request.user.username):
                            boolean = True
                        listbider.append((User.objects.get(username=i)).email)
                    #If the list of bider exists then it checks if this bider has bidded or not If not.
                    if boolean == False:
                        bider = Biders(bider=request.user.username, bidDate=datetime.now(),bidItemID=auc.id)
                        bider.save()
                        auc.bider.add(bider)
                        emailView(listbider,'Bid has been increased.','A Bid has been increased for this item.')
                    #If bider has already bided for this item.
                    else:
                        # This will take place when the user has not bided to any other auction before and is only one in the list
                        try:
                            bider = Biders.objects.get(bider=request.user.username)
                            bider.bidDate = datetime.now()
                            bider.save(update_fields=['bidDate'])
                            emailView(listbider,'Bid has been increased.','A Bid has been increased for this item.')
                        # This will occurs when same user has bided for multiple auction and error will occurs as it happen to be saved in same table
                        except:
                            bider_list = Biders.objects.filter(bider=request.user.username)
                            for i in bider_list:
                                if i.bidItemID == auc.id:
                                    i.bidDate = datetime.now()
                                    i.save(update_fields=['bidDate'])
                            emailView(listbider,'Bid has been increased.','A Bid has been increased for this item.')
                return JSONResponse({'msg': 'The bid for '+auc.title+' has been increased.'})
    #If the price is more or has been modified by other users before it was saved.
    else:
        auc = AuctionData.getById(id)
        return JSONResponse({ 'msg':'Logged in as '+request.user.username,
                                   'bid_invalid':'Minimum increase should be '+str(float(auc.cPrice)+0.01)})

class AuthView(APIView):
    authentication_classes = (BasicAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get_object(self, pk):
        try:
            return AuctionData.objects.get(pk=pk)
        except AuctionData.DoesNotExist:
            raise Http404

    def get(self, request, pk):
        auc = self.get_object(pk)
        serializer = AuctionSerializer(auc)
        return Response(serializer.data)